home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / bin / geomutil / ucd / make_frame.c < prev    next >
C/C++ Source or Header  |  1992-10-22  |  2KB  |  70 lines

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include "transform.h"
  4. #include "hpoint3.h"
  5. #include "vec4.h"
  6.  
  7. make_tform(p1, p2, p3, m)
  8. HPoint3 *p1, *p2, *p3;
  9. Transform m;
  10. /*     Generate a Euclidean isometry which moves (0,0,0) -> p1.
  11.    Furthermore, 
  12.     the vector (1,0,0) will go a vector tx based at p1 and ending at p2.
  13.     the vector (0,1,0) will go a vector ty based at p1, perpendicular to tx,
  14.    and lying in the plane of p1-p2-p3, in the "direction" of p3.    
  15.     the vector (0,0,1) will go a vector tz based at p1, perpendicular to tx and ty.
  16.     The rotational part is computed by make_rotation. See comments there */
  17. {
  18.     register int i;
  19.     HPoint3 nv1, nv2;
  20.     Transform trans;
  21.  
  22.     VSUB3(p2, p1, &nv1);
  23.     VSUB3(p3, p2, &nv2);
  24.     nv1.w = 1.0; nv2.w = 1.0;
  25.     NORMALIZE3(&nv1);
  26.     NORMALIZE3(&nv2);
  27.     if ( !make_rotation(&nv1, &nv2, m))    /* if collinear, use most recent rotation */
  28.     {
  29. #ifdef DEBUG
  30.     fprintf(stderr,"Non-independent vectors: make_rotation\n");
  31. #endif
  32.     return(-1);
  33.     }
  34.     /* compute translation to take p1->(0,0,0) */
  35.     TmTranslate(trans, p1->x, p1->y, p1->z);
  36.     /* first do the rotation, then the translation */
  37.     TmConcat(m, trans, m);
  38.     return(0);
  39.     }
  40.  
  41. /* make rotation that takes (1,0,0) to v1; and (0,1,0) to the orthog. proj of v2 onto
  42.    the perpendicular subspace of v1.  Return (0) if v1 and v2 are collinear. 
  43. */
  44. make_rotation(v1, v2, m)
  45. HPoint3 *v1, *v2;
  46. Transform m;
  47. {
  48.     int i;
  49.     double a;
  50.     HPoint3  t1, t2;
  51.  
  52.     a = VDOT3(v1, v2);
  53.     if (a > .9999 || a < -.9999)  return(0); 
  54.     t1.x = v1->x * a;
  55.     t1.y = v1->y * a;
  56.     t1.z = v1->z * a;
  57.     VSUB3(v2, &t1, &t2)         /* now t2 is orthogonal to v1 */
  58.     NORMALIZE3(&t2);
  59.     TmIdentity(m);
  60.     m[0][0] = v1->x;    m[0][1] = v1->y;     m[0][2] = v1->z;
  61.     m[1][0] = t2.x;    m[1][1] = t2.y;     m[1][2] = t2.z;
  62.     /* last row is cross product of the first two rows */
  63.     m[2][0] = v1->y*t2.z - v1->z*t2.y;
  64.     m[2][1] = v1->z*t2.x - v1->x*t2.z;
  65.     m[2][2] = v1->x*t2.y - v1->y*t2.x;
  66.  
  67.     return(1);
  68.  
  69. }
  70.